package cn.iocoder.yudao.module.system.dal.mysql.userbehavior;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.dal.dataobject.userbehavior.UserBehaviorStatsDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDate;
import java.util.List;

/**
 * 用户行为统计 Mapper
 *
 * @author 系统开发团队
 */
@Mapper
public interface UserBehaviorStatsMapper extends BaseMapperX<UserBehaviorStatsDO> {

    /**
     * 根据日期和统计类型查询
     */
    default UserBehaviorStatsDO selectByDateAndType(LocalDate statDate, Integer statType) {
        return selectOne(UserBehaviorStatsDO::getStatDate, statDate,
                UserBehaviorStatsDO::getStatType, statType);
    }

    /**
     * 根据日期范围和统计类型查询
     */
    default List<UserBehaviorStatsDO> selectByDateRangeAndType(LocalDate startDate, LocalDate endDate, Integer statType) {
        return selectList(new LambdaQueryWrapperX<UserBehaviorStatsDO>()
                .between(UserBehaviorStatsDO::getStatDate, startDate, endDate)
                .eq(UserBehaviorStatsDO::getStatType, statType)
                .orderByAsc(UserBehaviorStatsDO::getStatDate));
    }

    /**
     * 查询待计算的统计记录
     */
    default List<UserBehaviorStatsDO> selectPendingCalculation() {
        return selectList(UserBehaviorStatsDO::getCalculationStatus, 
                UserBehaviorStatsDO.CALCULATION_STATUS_PENDING);
    }

    /**
     * 查询最新的统计数据
     */
    default List<UserBehaviorStatsDO> selectLatestStats(Integer statType, Integer limit) {
        return selectList(new LambdaQueryWrapperX<UserBehaviorStatsDO>()
                .eq(statType != null, UserBehaviorStatsDO::getStatType, statType)
                .eq(UserBehaviorStatsDO::getCalculationStatus, UserBehaviorStatsDO.CALCULATION_STATUS_COMPLETED)
                .orderByDesc(UserBehaviorStatsDO::getStatDate)
                .last("LIMIT " + (limit != null ? limit : 10)));
    }

    /**
     * 查询行为趋势
     */
    default List<UserBehaviorStatsDO> selectBehaviorTrend(LocalDate startDate, LocalDate endDate, Integer statType) {
        return selectList(new LambdaQueryWrapperX<UserBehaviorStatsDO>()
                .between(UserBehaviorStatsDO::getStatDate, startDate, endDate)
                .eq(statType != null, UserBehaviorStatsDO::getStatType, statType)
                .eq(UserBehaviorStatsDO::getCalculationStatus, UserBehaviorStatsDO.CALCULATION_STATUS_COMPLETED)
                .orderByAsc(UserBehaviorStatsDO::getStatDate));
    }

    /**
     * 统计计算状态数量
     */
    default Long countByCalculationStatus(Integer calculationStatus) {
        return selectCount(UserBehaviorStatsDO::getCalculationStatus, calculationStatus);
    }

    /**
     * 统计指定日期的记录数量
     */
    default Long countByDate(LocalDate statDate) {
        return selectCount(UserBehaviorStatsDO::getStatDate, statDate);
    }

    /**
     * 统计已完成计算的记录数量
     */
    default Long countCompletedByDate(LocalDate statDate) {
        return selectCount(new LambdaQueryWrapperX<UserBehaviorStatsDO>()
                .eq(UserBehaviorStatsDO::getStatDate, statDate)
                .eq(UserBehaviorStatsDO::getCalculationStatus, UserBehaviorStatsDO.CALCULATION_STATUS_COMPLETED));
    }

    /**
     * 删除过期数据
     */
    default int deleteExpiredData(LocalDate beforeDate) {
        return delete(new LambdaQueryWrapperX<UserBehaviorStatsDO>()
                .lt(UserBehaviorStatsDO::getStatDate, beforeDate));
    }

    /**
     * 查询功能使用峰值
     */
    default UserBehaviorStatsDO selectPeakFeatureUsage(LocalDate startDate, LocalDate endDate, Integer statType) {
        return selectOne(new LambdaQueryWrapperX<UserBehaviorStatsDO>()
                .between(UserBehaviorStatsDO::getStatDate, startDate, endDate)
                .eq(statType != null, UserBehaviorStatsDO::getStatType, statType)
                .eq(UserBehaviorStatsDO::getCalculationStatus, UserBehaviorStatsDO.CALCULATION_STATUS_COMPLETED)
                .orderByDesc(UserBehaviorStatsDO::getFeatureUsageUsers)
                .last("LIMIT 1"));
    }

    /**
     * 查询功能使用最低值
     */
    default UserBehaviorStatsDO selectLowestFeatureUsage(LocalDate startDate, LocalDate endDate, Integer statType) {
        return selectOne(new LambdaQueryWrapperX<UserBehaviorStatsDO>()
                .between(UserBehaviorStatsDO::getStatDate, startDate, endDate)
                .eq(statType != null, UserBehaviorStatsDO::getStatType, statType)
                .eq(UserBehaviorStatsDO::getCalculationStatus, UserBehaviorStatsDO.CALCULATION_STATUS_COMPLETED)
                .orderByAsc(UserBehaviorStatsDO::getFeatureUsageUsers)
                .last("LIMIT 1"));
    }

    /**
     * 分页查询用户行为统计
     */
    default PageResult<UserBehaviorStatsDO> selectPage(LocalDate startDate, LocalDate endDate,
                                                        Integer statType, Integer calculationStatus,
                                                        int pageNo, int pageSize) {
        PageParam pageParam = new PageParam();
        pageParam.setPageNo(pageNo);
        pageParam.setPageSize(pageSize);
        return selectPage(pageParam, new LambdaQueryWrapperX<UserBehaviorStatsDO>()
                .between(startDate != null && endDate != null, UserBehaviorStatsDO::getStatDate, startDate, endDate)
                .eq(statType != null, UserBehaviorStatsDO::getStatType, statType)
                .eq(calculationStatus != null, UserBehaviorStatsDO::getCalculationStatus, calculationStatus)
                .orderByDesc(UserBehaviorStatsDO::getStatDate));
    }

    /**
     * 插入或更新统计数据
     */
    default void insertOrUpdateStats(UserBehaviorStatsDO stats) {
        UserBehaviorStatsDO existing = selectByDateAndType(stats.getStatDate(), stats.getStatType());
        if (existing != null) {
            stats.setId(existing.getId());
            updateById(stats);
        } else {
            insert(stats);
        }
    }
}